# !/usr/bin/env python
# -*- coding:utf-8 -*-
# @FileName  :v_model.py
# @Time      :2025/7/18 10:13
# @Author    :aiyimu

import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.font_manager import FontProperties

# 设置中文字体（确保系统有支持中文的字体，如SimHei）
plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置默认字体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

# 创建画布
fig, ax = plt.subplots(figsize=(10, 8))

# 定义节点和位置（V字形布局）
nodes = {
    "用户需求": (-2, 3),
    "需求分析与系统设计": (-2, 2),
    "概要设计": (-2, 1),
    "详细设计": (-2, 0),
    "编码": (0, -1),  # 底部顶点
    "单元测试": (2, 0),
    "集成测试": (2, 1),
    "系统测试": (2, 2),
    "验收测试": (2, 3)
}

# 绘制连接线（左侧开发阶段）
left_flow = ["用户需求", "需求分析与系统设计", "概要设计", "详细设计", "编码"]
for i in range(len(left_flow) - 1):
    x1, y1 = nodes[left_flow[i]]
    x2, y2 = nodes[left_flow[i + 1]]
    ax.plot([x1, x2], [y1, y2], 'b-', linewidth=2)

# 绘制连接线（右侧测试阶段）
right_flow = ["编码", "单元测试", "集成测试", "系统测试", "验收测试"]
for i in range(len(right_flow) - 1):
    x1, y1 = nodes[right_flow[i]]
    x2, y2 = nodes[right_flow[i + 1]]
    ax.plot([x1, x2], [y1, y2], 'r-', linewidth=2)

# 绘制虚线对应关系（V模型核心逻辑）
correspondences = [
    ("详细设计", "集成测试", "green"),
    ("概要设计", "系统测试", "purple"),
    ("需求分析与系统设计", "验收测试", "orange")
]
for src, dst, color in correspondences:
    x1, y1 = nodes[src]
    x2, y2 = nodes[dst]
    ax.plot([x1, x2], [y1, y2], linestyle='--', color=color, alpha=0.6)

# 绘制节点（圆形+文字）
for name, (x, y) in nodes.items():
    color = 'skyblue' if name in left_flow else 'lightcoral'
    ax.add_patch(patches.Circle((x, y), radius=0.3, facecolor=color, edgecolor='black'))
    ax.text(x, y, name, ha='center', va='center', fontsize=10)

# 添加标题和注释
ax.set_title("V模型软件开发流程", fontsize=14, pad=20)
ax.text(-3, 3.5, "开发阶段", color='blue', fontsize=12)
ax.text(2.5, 3.5, "测试阶段", color='red', fontsize=12)

# 隐藏坐标轴
ax.set_xlim(-4, 4)
ax.set_ylim(-2, 4)
ax.axis('off')

plt.tight_layout()
plt.savefig("v_model.png", dpi=300, bbox_inches='tight')  # 保存图片
plt.show()